home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / waisgate / wutil.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  48KB  |  1,892 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4. */
  5.  
  6. /*--------------------------------------------------------------------------
  7.  * ABSTRACT:    WAIS_TOOLS
  8.  *
  9.  * AUTHOR
  10.  *   M. Tracy Shen
  11.  *
  12.  *
  13.  *------------------------------------------------------------------------*/
  14.  
  15. #ifndef lint
  16. static char *RCSid = "$Header: /tmp_mnt/net/quake/proj/wais/wais-8-b5/ir/RCS/wutil.c,v 1.3 92/02/12 13:58:52 jonathan Exp $";
  17. #endif
  18.  
  19. /* Change log:
  20.  * $Log:    wutil.c,v $
  21.  * Revision 1.3  92/02/12  13:58:52  jonathan
  22.  * Added "$Log" so RCS will put the log message in the header
  23.  * 
  24.  * 
  25.  * ported to Unix and SaberC -brewster 7/7/90
  26.  * added in bug fixes -Tracy 11/14/90
  27.  */
  28.  
  29. /*  
  30.  * INCLUDE EXTERNAL CONSTANTS                                         
  31.  */
  32.  
  33. #include "futil.h"
  34. #include <ctype.h>
  35. #include "zprot.h"
  36. #include "zutil.h"
  37. #include "wprot.h"
  38. #include <string.h>
  39. #include "wutil.h"
  40.  
  41.  
  42. /*  
  43.  * DEFINE LOCAL CONSTANTS
  44.  */
  45.  
  46.  
  47. #define CARRIAGE_RETURN 13
  48. #define LINE_FEED 10
  49. #define  ESC 27
  50. #define  DC1 17
  51. #define  DC3 19
  52. #define  ETS  3
  53.  
  54. #define FF  12
  55.  
  56.  
  57. #define INIT_CMD   1
  58. #define SEARCH_CMD 2
  59. #define EXTRACT_CMD 3
  60. #define STOP_CMD    4
  61.  
  62. #define MAX_CMD 4  /* init, query search, extract story, stop */
  63. #define MAX_BUFFER_LENGTH 10000 /* kludge -brewster */
  64.  
  65. /*
  66.  * DEFINE MACROS
  67.  */
  68.  
  69. #ifndef MIN
  70. #define MIN(a,b)  (a > b ? b : a)
  71. #endif
  72.  
  73. #define BIT(n)  (1L << n)
  74.  
  75. /*
  76.  * define global variables
  77.  */
  78.  
  79.  /* WAIS element names */
  80.     char *elm_name_tbl[] = {  ES_DocumentHeader
  81.                     ,ES_DocumentShortHeader
  82.                     ,ES_DocumentLongHeader
  83.                     ,ES_DocumentText
  84.                     ,ES_DocumentHeadline
  85.                     ,ES_DocumentCodes
  86.                     };
  87.  
  88. #ifdef TEST
  89.  
  90. twais_tmplt_typ1_srch_apdu _AP((char* buff,long* buff_len));
  91. twais_tmplt_typ3_srch_apdu _AP((char* buff,long* buff_len));
  92. dsply_doc_hdr_record _AP((WAISDocumentHeader* record));
  93. dsply_short_hdr_record _AP((WAISDocumentHeader* record));
  94.  
  95. main()
  96. {
  97.   char cmd[4096];
  98.   long cmd_len;
  99.  
  100.   printf("\n\n test template request apdu\n\n");
  101.  
  102.   do 
  103.     twais_format_req_apdu( TRUE, cmd, &cmd_len);
  104.   while ( cmd_len > 0 );
  105.  
  106.     
  107.  
  108.   printf("\n\n test formating request apdu\n\n");
  109.   do 
  110.     twais_format_req_apdu( FALSE, cmd, &cmd_len);
  111.   while ( cmd_len > 0 );
  112.  
  113.  
  114.   printf("\n\n test display init response apdu\n\n");
  115.  
  116.   twais_tmplt_init_rsp_apdu(  cmd, &cmd_len);
  117.   twais_dsply_rsp_apdu( cmd, cmd_len);
  118.  
  119.   printf("\n\n test display type3 search response apdu\n\n");
  120.   twais_tmplt_typ3_srch_rsp_apdu(  cmd, &cmd_len);
  121.   twais_dsply_rsp_apdu( cmd, cmd_len);
  122.  
  123.   printf("\n\n test display type1 search response apdu\n\n");
  124.   twais_tmplt_typ1_stry_rsp_apdu( cmd, &cmd_len);
  125.   twais_dsply_rsp_apdu( cmd, cmd_len);
  126.  
  127. }                /* main */
  128.  
  129. #endif
  130.  
  131.  
  132. static void get_int_item _AP((char* itm_name, long *itm_val));
  133.  
  134. static void
  135. get_int_item(itm_name, itm_val)
  136. char *itm_name;
  137. long  *itm_val;
  138. {
  139.   printf("    %s (integer): ", itm_name);
  140.   scanf("%ld", itm_val);
  141. }
  142.  
  143. static void get_str_item _AP((char* itm_name,char*  itm_val));
  144.  
  145. static void
  146. get_str_item(itm_name, itm_val)
  147. char *itm_name;
  148. char *itm_val;
  149. {
  150.   printf("    %s (string): ", itm_name);
  151.   scanf("%s", itm_val);
  152. }
  153.  
  154. static void get_line_item _AP((char* itm_name,char*  itm_val));
  155.  
  156. static void
  157. get_line_item(itm_name, itm_val)
  158. char *itm_name;
  159. char *itm_val;
  160. {
  161.    
  162.   printf("    %s (one line string):\n", itm_name);
  163.   gets( itm_val);
  164.   if ( itm_val[0] == 0 )
  165.     gets(itm_val);
  166. }
  167.  
  168. static void get_req_type _AP((long* req_type));
  169.  
  170. static void
  171. get_req_type( req_type)
  172. long *req_type;
  173. {
  174.  
  175.   printf("\n\n");
  176.   printf(" request type 1)init  2)query search 3)extract story 4)stop: ");
  177.   scanf("%ld", req_type);
  178.  
  179. }                /* get_req_type */
  180.  
  181. /*
  182.  * "twais_format_req_apdu"  This function gets request message.  It reads the
  183.  *   request message into the the specified buffer.
  184.  *   It returns the the length of the data 
  185.  *   written into the buffer as an output parameter.  
  186.  *   A zero length value indicates "end session".
  187.  *
  188.  * return values:
  189.  *  none
  190.  */
  191. void 
  192. twais_format_req_apdu(use_template,apdu_buff,len)
  193. boolean use_template;
  194. char* apdu_buff;
  195. long* len;
  196. /* use_template :  (I) flag indicating whether use template apdu */
  197. /* apdu_buff    :  (O) buffer to put apdu */
  198. /* len          :  (O) number of bytes written to the buffer */
  199. {
  200.   long req_type;
  201.  
  202.   do { 
  203.  
  204.     get_req_type( &req_type);
  205.  
  206.     switch (req_type) {
  207.     case INIT_CMD: 
  208.       *len = twais_format_init_apdu( use_template, apdu_buff);
  209.       break;
  210.     case SEARCH_CMD: 
  211.       *len = twais_format_typ3_srch_apdu( use_template, apdu_buff);
  212.       break;
  213.     case EXTRACT_CMD: 
  214.       *len = twais_format_typ1_srch_apdu( use_template,  apdu_buff);
  215.       break;
  216.     case STOP_CMD: 
  217.       *len = 0;
  218.       break;
  219.     default: 
  220.       break;
  221.     
  222.     }                /* end switch */
  223.   }  
  224.   while ( req_type < 1 || req_type > MAX_CMD );
  225.  
  226. }                /* twais_format_req_apdu */
  227.  
  228.  
  229.  
  230. /*
  231.  * "twais_format_init_apdu"
  232.  *   prompt user information to format an init apdu and 
  233.  *   write the apdu to the specified buffer
  234.  *
  235.  * function return:
  236.  *   number of bytes written to the buffer 
  237.  */
  238. long 
  239. twais_format_init_apdu(use_template,apdu_buff)
  240. boolean use_template;
  241. char* apdu_buff;
  242.  
  243. /* use_template :  (I) flag indicating whether use template apdu */
  244. /* apdu_buff    :  (O) buffer to put apdu */
  245. {
  246.   InitAPDU *init1;
  247.   char  *end_ptr;
  248.   long len;
  249.   long pref_msg_size;
  250.   long max_rec_size;
  251.   any refID;
  252.   char ref_id[128];
  253.  
  254.   if ( use_template ) {
  255.     twais_tmplt_init_apdu(apdu_buff, &len);
  256.     return( len);
  257.   }      
  258.  
  259.   get_int_item( "prefered message size", &pref_msg_size);
  260.   get_int_item( "maximum record size", &max_rec_size);
  261.  
  262.   get_str_item("reference id", ref_id);
  263.   refID.size = strlen(ref_id);
  264.   refID.bytes = &ref_id[0];
  265.  
  266.   init1 = makeInitAPDU(WILL_USE,WILL_NOT_USE,WILL_NOT_USE,WILL_NOT_SUPPORT,
  267.                        WILL_NOT_SUPPORT,
  268.                        pref_msg_size,
  269.                        max_rec_size, NULL,
  270.                        defaultImplementationID(),defaultImplementationName(),
  271.                        defaultImplementationVersion(), &refID,NULL);
  272.  
  273.   { long buffer_len = MAX_BUFFER_LENGTH;
  274.     end_ptr = writeInitAPDU(init1, apdu_buff, &buffer_len);
  275.   }
  276.   freeInitAPDU(init1);
  277.   len = (long)end_ptr - (long)apdu_buff;
  278.   return(len);  
  279. }                /* twais_format_init_apdu */
  280.  
  281. /* 
  282.  * "twais_format_typ3_srch_apdu"  
  283.  *  prompt user information to form a relevance feedback search apdu and
  284.  *  write the apdu to the specified buffer
  285.  *
  286.  * function return:
  287.  *   number of bytes written to the buffer 
  288.  */
  289. long 
  290. twais_format_typ3_srch_apdu(use_template,apdu_buff)
  291. boolean use_template;
  292. char* apdu_buff;
  293.  
  294. /* use_template :  (I) flag indicating whether use template apdu */
  295. /* apdu_buff    :  (O) buffer to put apdu */
  296. {
  297.   SearchAPDU *search;
  298.   char  *end_ptr;
  299.   long len;
  300.   long small, large, medium;
  301.  
  302.   char temp_string[80];
  303.  
  304.   long num_databases, num_elmsets, i;
  305.   char **database_names_ptr;
  306.   char *database_names[11];
  307.   char database_name[10][129];
  308.   long  elm_type;
  309.   char *elm_names[21];
  310.   char elm_name[20][128];
  311.   char **elm_names_ptr = &elm_names[0];
  312.  
  313.   any refID;
  314.   char ref_id[256];
  315.   char seed_words[257];
  316.  
  317.   DocObj *DocObjs[5];
  318.  
  319.   DocObj **DocObjsPtr = 0;
  320.   long DateFactor;
  321.   char BeginDateRange[9], EndDateRange[9];
  322.   long maxDocsRetrieved;
  323.   long num, sw;
  324.   char doc_id[4][200];
  325.   any docID[4];
  326.   long ChunkCode;
  327.   any Start[4], End[4];   
  328.   char start_pos[4][10], end_pos[4][10];
  329.   long start_ipos, end_ipos;
  330.   WAISSearch *query;
  331.   long count;
  332.   for(count = 0; count < 5; count++){
  333.     DocObjs[count] = 0;        /* added by brewster */
  334.   }
  335.  
  336.   if ( use_template ) {
  337.     twais_tmplt_typ3_srch_apdu(apdu_buff, &len);
  338.     return( len);
  339.   }      
  340.  
  341.  
  342.   get_int_item("small set upper bound", &small);
  343.   get_int_item("large set lower bound", &large);
  344.   get_int_item("medium set present number", &medium);
  345.  
  346.   get_int_item("number of databases(max 10, 0 search entire databases)", &num_databases);
  347.  
  348.   if ( num_databases == 0 ) {
  349.     database_names_ptr = 0;
  350.   }
  351.  
  352.   else {
  353.     database_names_ptr = &database_names[0];
  354.     database_names[num_databases] = 0;  
  355.     for ( i=0; i < num_databases; i++ ) {
  356.       database_names[i] = &database_name[i][0];
  357.       sprintf( temp_string,"database name %ld", (i+1) );
  358.       get_str_item(temp_string, database_name[i]);
  359.     }
  360.   }
  361.  
  362.   get_int_item("number of database-element_set pairs(max 10)", &num_elmsets);
  363.  
  364.   if ( num_elmsets == 0 ) 
  365.     elm_names_ptr = 0;
  366.   else {
  367.     elm_names[num_elmsets * 2 ] = 0;
  368.     for ( i=0; i < num_elmsets; i++ ) {
  369.       elm_names[i*2] = &elm_name[i*2][0];
  370.       sprintf( temp_string,"database name %ld", (i+1) );
  371.       get_str_item(temp_string, &elm_name[i*2][0]);
  372.  
  373.       get_int_item("  element type 0)default 1)DocHeaders 2)ShortHeaders\n        3)LongHeaders 4)Text 5)HeadLines 6)Codes", 
  374.            &elm_type);
  375.       if ( (elm_type < 1) || (elm_type > 6) )
  376.     elm_type = 1;
  377.       elm_names[i*2+1] = &elm_name[i*2+1][0];
  378.       strcpy( &elm_name[i*2+1][0], elm_name_tbl[elm_type-1]);
  379.     }
  380.   }
  381.  
  382.  
  383.   get_str_item("reference id", ref_id);
  384.   refID.size = strlen(ref_id);
  385.   refID.bytes = &ref_id[0];
  386.  
  387.   /*
  388.    * format wais search query
  389.    */
  390.   /* fill in the user information */
  391.  
  392.   get_line_item("seed_words", seed_words);
  393.   get_int_item("number of relevance feedback documents(max 4)", &num);
  394.   if ( num > 0 ) {
  395.  
  396.     if ( num > 4 )
  397.       num = 4;
  398.     DocObjsPtr = &DocObjs[0];
  399.     for ( i=0; i< num; i++) {
  400.       docID[i].bytes = &doc_id[i][0];
  401.       sprintf(temp_string, "document id %ld", (i+1));
  402.       get_str_item(temp_string, &doc_id[i][0]);
  403.       docID[i].size = strlen( &doc_id[i][0]);
  404.       get_int_item("  (1)whole story (2)part story", &sw);
  405.       if ( sw == 1) {
  406.     DocObjs[i] = makeDocObjUsingWholeDocument( &docID[i],NULL);
  407.       }
  408.       else {
  409.     get_int_item("  ChunkCode (1)byte (2)line (3)parag", &ChunkCode);
  410.     if ( ChunkCode == 1 ) {
  411.       get_int_item("  start position", &start_ipos);
  412.       get_int_item("  end position", &end_ipos);
  413.       DocObjs[i] = makeDocObjUsingBytes( &docID[i], NULL,
  414.                         start_ipos, end_ipos);
  415.     }
  416.     else if ( ChunkCode == 2 ) {
  417.       get_int_item("  start position", &start_ipos);
  418.       get_int_item("  end position", &end_ipos);
  419.       DocObjs[i] = makeDocObjUsingLines( &docID[i], NULL,
  420.                         start_ipos, end_ipos);
  421.     }
  422.     else {
  423.       get_str_item("  start position", &start_pos[i][0]);
  424.       get_str_item("  end position", &end_pos[i][0]);
  425.       Start[i].size = strlen( &start_pos[i][0]);
  426.       Start[i].bytes = &start_pos[i][0];
  427.       End[i].size = strlen( &end_pos[i][0]);
  428.       End[i].bytes = &end_pos[i][0];
  429.       DocObjs[i] = makeDocObjUsingParagraphs( &docID[i], NULL,
  430.                          &Start[i], &End[i]);
  431.     }
  432.       }                /* end if-else */
  433.     }                /* end for */
  434.   }                /* end if */
  435.    
  436.   get_int_item("DateFactor (1-independent,2-later,3-earlier,4-range)", &DateFactor);
  437.   if ( DateFactor == 2 || DateFactor == 4) 
  438.     get_str_item("begin date  (yyyymmdd)", BeginDateRange);
  439.   else
  440.     BeginDateRange[0] = '\0';
  441.   if ( DateFactor == 3 || DateFactor == 4) 
  442.     get_str_item("end date (yyyymmdd)", EndDateRange);
  443.   else
  444.     EndDateRange[0] = '\0';
  445.  
  446.   get_int_item("max. documents retrieved", &maxDocsRetrieved);
  447.  
  448.   query = makeWAISSearch( seed_words, DocObjsPtr, 0L,
  449.              DateFactor, BeginDateRange, EndDateRange,
  450.              maxDocsRetrieved);
  451.  
  452.   search = makeSearchAPDU( small, large, medium, 
  453.               1L,    /* replace indicator */
  454.               "FOO", /* result set name */
  455.               database_names_ptr, /* database name */   
  456.               QT_RelevanceFeedbackQuery, /* query_type */
  457.               elm_names_ptr, /* element name */
  458.               &refID, query);
  459.  
  460.   {
  461.     long buffer_len = MAX_BUFFER_LENGTH;
  462.     end_ptr = writeSearchAPDU(search, apdu_buff, &buffer_len);
  463.   }
  464.   len = (long)end_ptr - (long)apdu_buff;
  465.  
  466.   i =0;
  467.   while ( DocObjs[i] != 0 ) {
  468.     CSTFreeDocObj( DocObjs[i]);
  469.     i++;
  470.   }
  471.  
  472.   CSTFreeWAISSearch(query);
  473.  
  474.   freeSearchAPDU(search);
  475.  
  476.   return(len);
  477.  
  478. }                /* twais_format_typ3_srch_apdu */
  479.  
  480. /* 
  481.  * "twais_format_typ1_srch_apdu"  
  482.  *  prompt user information to form a text retrieval search apdu and
  483.  *  write the apdu to the specified buffer
  484.  *
  485.  * function return:
  486.  *   number of bytes written to the buffer 
  487.  */
  488. long
  489. twais_format_typ1_srch_apdu(use_template,apdu_buff)
  490. boolean use_template;
  491. char* apdu_buff;
  492.  
  493. /* use_template :  (I) flag indicating whether use template apdu */
  494. /* apdu_buff    :  (O) buffer to put apdu */
  495. {
  496.   SearchAPDU *search;
  497.   char  *end_ptr;
  498.   long len;
  499.   long small, large, medium;
  500.  
  501.   char temp_string[80];
  502.  
  503.   long num_databases, num_elmsets, i;
  504.   char **database_names_ptr;
  505.   char *database_names[11];
  506.   char database_name[10][129];
  507.   long  elm_type;
  508.   char *elm_names[21];
  509.   char elm_name[20][128];
  510.   char **elm_names_ptr = &elm_names[0];
  511.  
  512.   any refID;
  513.   char ref_id[256];
  514.  
  515.   any *query;            /* changed by brewster from char * */
  516.   DocObj *DocObjs[11];
  517.   long num_doc;
  518.   long sw;
  519.   char doc_id[10][200];
  520.   any docID[10];
  521.   long ChunkCode;
  522.   any Start[10], End[10];   
  523.   long start_ipos, end_ipos;
  524.   char start_pos[10][10], end_pos[10][10];
  525.  
  526.   long use_text = 0;
  527.  
  528.  
  529.   if ( use_template ) {
  530.     twais_tmplt_typ1_srch_apdu(apdu_buff, &len);
  531.     return( len);
  532.   }      
  533.  
  534.  
  535.   get_int_item("small set upper bound", &small);
  536.   get_int_item("large set lower bound", &large);
  537.   get_int_item("medium set present number", &medium);
  538.  
  539.   get_int_item("number of databases(max 10, 0 search entire databases)", &num_databases);
  540.  
  541.   if ( num_databases == 0 ) {
  542.     database_names_ptr = 0;
  543.   }
  544.   else {
  545.     database_names_ptr = &database_names[0];
  546.     database_names[num_databases] = 0;  
  547.     for ( i=0; i < num_databases; i++ ) {
  548.       database_names[i] = &database_name[i][0];
  549.       sprintf(temp_string, "database name %ld", (i+1));
  550.       get_str_item( temp_string, database_name[i]);
  551.     }
  552.   }
  553.  
  554.   get_int_item("number of database-element_set pairs(max 10)", &num_elmsets);
  555.  
  556.   if ( num_elmsets == 0 ) 
  557.     elm_names_ptr = 0;
  558.   else {
  559.     elm_names[num_elmsets * 2 ] = 0;
  560.     for ( i=0; i < num_elmsets; i++ ) {
  561.       elm_names[i*2] = &elm_name[i*2][0];
  562.       sprintf( temp_string,"database name %ld", (i+1) );
  563.       get_str_item(temp_string, &elm_name[i*2][0]);
  564.  
  565.       get_int_item("  element type 0)default 1)DocHeaders 2)ShortHeaders\n        3)LongHeaders 4)Text 5)HeadLines 6)Codes", 
  566.            &elm_type);
  567.       if ( (elm_type < 1) || (elm_type > 6) )
  568.     elm_type = 1;
  569.       if ( elm_type == 4)  use_text++;
  570.       elm_names[i*2+1] = &elm_name[i*2+1][0];
  571.       strcpy( &elm_name[i*2+1][0], elm_name_tbl[elm_type-1]);
  572.     }
  573.   }
  574.  
  575.   get_str_item("reference id", ref_id);
  576.   refID.size = strlen(ref_id);
  577.   refID.bytes = &ref_id[0];
  578.  
  579.   /*
  580.    * format type 1 query
  581.    */
  582.   get_int_item("num of documents to retrieve (max 10)", &num_doc);
  583.   if ( num_doc > 10 ) num_doc = 10;
  584.   if ( num_doc < 1 ) num_doc = 1;
  585.  
  586.   DocObjs[num_doc] = 0;
  587.  
  588.   for ( i=0; i < num_doc; i++ ) {
  589.     docID[i].bytes = &doc_id[i][0];
  590.  
  591.     sprintf( temp_string, "document id %ld", (i+1));
  592.     get_str_item(temp_string, &doc_id[i][0]);
  593.     docID[i].size = strlen( &doc_id[i][0]);
  594.         
  595.     if ( use_text == 0 )
  596.       DocObjs[i] = makeDocObjUsingWholeDocument( &docID[i],NULL);
  597.     else {         
  598.       get_int_item("  (1)whole story (2)part story", &sw);
  599.       if ( sw == 1) {
  600.     DocObjs[i] = makeDocObjUsingWholeDocument( &docID[i],NULL);
  601.       }
  602.       else {
  603.     get_int_item("  ChunkCode (1)byte (2)line (3)parag", &ChunkCode);
  604.     if ( ChunkCode == 1 ) {
  605.       get_int_item("  start position", &start_ipos);
  606.       get_int_item("  end position", &end_ipos);
  607.       DocObjs[i] = makeDocObjUsingBytes( &docID[i], NULL,
  608.                         start_ipos, end_ipos);
  609.     }
  610.     else if ( ChunkCode == 2 ) {
  611.       get_int_item("  start position", &start_ipos);
  612.       get_int_item("  end position", &end_ipos);
  613.       DocObjs[i] = makeDocObjUsingLines( &docID[i], NULL,
  614.                         start_ipos, end_ipos);
  615.     }
  616.     else {
  617.       get_str_item("  start position", &start_pos[i][0]);
  618.       get_str_item("  end position", &end_pos[i][0]);
  619.       Start[i].size = strlen( &start_pos[i][0]);
  620.       Start[i].bytes = &start_pos[i][0];
  621.       End[i].size = strlen( &end_pos[i][0]);
  622.       End[i].bytes = &end_pos[i][0];
  623.       DocObjs[i] = makeDocObjUsingParagraphs( &docID[i], NULL,
  624.                          &Start[i], &End[i]);
  625.     }
  626.       }                /* end if-else */
  627.     }
  628.   }
  629.  
  630.   query = makeWAISTextQuery(DocObjs);   
  631.  
  632.  
  633.   search = makeSearchAPDU( small, large, medium, 
  634.               1L,    /* replace indicator */
  635.               "FOO", /* result set name */
  636.               database_names_ptr, /* database name */   
  637.               QT_TextRetrievalQuery, /* query_type */
  638.               elm_names_ptr, /* element name */
  639.               &refID, query);
  640.  
  641.   {
  642.     long buffer_len = MAX_BUFFER_LENGTH;
  643.     end_ptr = writeSearchAPDU(search, apdu_buff, &buffer_len);
  644.   }
  645.   len = (long)end_ptr - (long)apdu_buff;
  646.  
  647.   i =0;
  648.   while ( DocObjs[i] != 0) {
  649.     CSTFreeDocObj( DocObjs[i]);
  650.     i++;
  651.   }
  652.  
  653.   CSTFreeWAISTextQuery( query);
  654.  
  655.   freeSearchAPDU(search);
  656.  
  657.   return(len);
  658.  
  659. }                /* twais_format_typ1_srch_apdu */
  660.  
  661. static void print_hdline _AP((char* hdline));
  662.  
  663. static void print_hdline(hdline)
  664. char *hdline;
  665. {
  666.   char buf[301];
  667.   long len, i;
  668.  
  669.   len = strlen(hdline);
  670.   if (len > 300 )
  671.     len =300;
  672.   for ( i=0; i< len; i++ )
  673.     if ( hdline[i] > 31 && hdline[i] < 127 )
  674.       buf[i] = hdline[i];
  675.     else
  676.       buf[i] = '@';         
  677.   buf[i] = 0;
  678.   printf("     Headline:  %s\n", buf);
  679. }
  680.  
  681.  
  682. static void print_any _AP((char* title,any*  any_ptr));
  683.  
  684. static void print_any( title, any_ptr)
  685. char *title;
  686. any *any_ptr;
  687. {
  688.   long i;
  689.   printf("%s", title);
  690.   if ( any_ptr ) {
  691.     for ( i=0; i < any_ptr->size; i++)
  692.      { if (isprint(any_ptr->bytes[i]))
  693.      printf("%c", any_ptr->bytes[i]);
  694.        else
  695.      printf("%ld", (long)any_ptr->bytes[i]);
  696.      }
  697.     printf("\n");
  698.   } 
  699. }
  700.  
  701.  
  702.   
  703. static void dsply_long_hdr_record _AP((WAISDocumentLongHeader* record));
  704.  
  705. static void dsply_long_hdr_record(record)
  706. WAISDocumentLongHeader *record;
  707. /*
  708.  * 'dsply_long_hdr_record'
  709.  *   display one WAIS long header  record 
  710.  */
  711. {
  712.   printf(" LongHeaders\n");
  713.  
  714.   print_any("     DocumentID:  ", record->DocumentID);
  715.  
  716.   printf("     VersionNumber:  %ld\n", record->VersionNumber);
  717.  
  718.   printf("     Score:  %ld,  BestMatch:  %ld\n", 
  719.      record->Score,
  720.      record->BestMatch);
  721.  
  722.   printf("     DocumentLength:  %ld,  Lines:  %ld\n", 
  723.      record->DocumentLength,
  724.      record->Lines);
  725.  
  726.   if ( record->Source )
  727.     printf("     Source:  %s\n", record->Source);
  728.  
  729.   if ( record->Date )
  730.     printf("     Date:  %s\n", record->Date);
  731.  
  732.   if ( record->OriginCity)
  733.     printf("     OriginCity:  %s\n", record->OriginCity);
  734.  
  735.   if ( record->Headline)
  736. #ifdef FOR_DUM_TERM
  737.     print_hdline(record->Headline);
  738. #else
  739.   printf("     Headline:  %s\n", record->Headline);
  740. #endif
  741.  
  742.   if ( record->StockCodes)
  743.     printf("     StockCodes:  %s", record->StockCodes);
  744.  
  745.   if ( record->CompanyCodes )
  746.     printf("     CompanyCodes:  %s", record->CompanyCodes);
  747.  
  748.   if ( record->IndustryCodes)
  749.     printf("     IndustryCodes:  %s", record->IndustryCodes);
  750.  
  751.   printf("\n");
  752. }
  753. /*
  754.  * dsply_text
  755.  *  display story text
  756.  */
  757. #define TEXT_LINES_PER_PAGE 18
  758. #define  DQ_PAR_LEN   3
  759. #define  DQ_EOL_LEN   1
  760. #define  DQ_MAX_LINE_LEN  256
  761.  
  762. #define  PRINT_LINE(line, ndx, line_cnt,text_ptr,last_ptr,continue_viewing)\
  763.          line[ndx] = NULL;\
  764.          line_cnt++; \
  765.          printf("%s\n", line);\
  766.          ndx = 0;\
  767.          if ( (line_cnt == TEXT_LINES_PER_PAGE) && (text_ptr <= last_ptr)) {\
  768.             line_cnt = 0;\
  769.             printf("\n  ... more to come, enter 1 to continue or 0 to stop: ");\
  770.             scanf("%ld", &continue_viewing);\
  771.             }
  772.  
  773. #if 0
  774. /*
  775.  * try to format text
  776.  */
  777. dsply_text( size, text)
  778. long size;
  779. char *text;
  780. {
  781.   char  line[DQ_MAX_LINE_LEN +1];
  782.   char *last_ptr;
  783.   char *text_ptr;
  784.   long  ndx;
  785.   long line_cnt = 0;
  786.   long continue_viewing = 1;
  787.     
  788.   text_ptr = text;
  789.  
  790.   last_ptr = text_ptr + size;
  791.  
  792.   while ( (*text_ptr != ETS) && (text_ptr < last_ptr) ) {
  793.     if (  *text_ptr++ == ESC ) {
  794.       if (*text_ptr++ == 'k') 
  795.     break;
  796.     }
  797.   }
  798.  
  799.   if ( text_ptr >= last_ptr ) {
  800.     printf("**** ERROR in display text -- could not find text\n");
  801.     return;
  802.   }
  803.  
  804.   ndx = 0;
  805.  
  806.   while ( (continue_viewing == 1) && ( *text_ptr != ETS) &&
  807.      (text_ptr < last_ptr) ) {
  808.  
  809.     /* paragraph id -- skip */
  810.     if ( *text_ptr == ESC) {
  811.       text_ptr++;
  812.       if ( *text_ptr == 'l' )
  813.     text_ptr++;
  814.       if ( ndx > 0 ) {
  815.     PRINT_LINE(line, ndx,line_cnt,text_ptr,last_ptr,continue_viewing);  
  816.       }
  817.       ndx = DQ_PAR_LEN;
  818.       strncpy( line, text_ptr, ndx);
  819.       text_ptr += DQ_PAR_LEN;
  820.       PRINT_LINE(line, ndx,line_cnt,text_ptr,last_ptr,continue_viewing);  
  821.     }
  822.  
  823.     /* highlight & dehighlight markers -- skip */
  824.     else if ( (*text_ptr == DC1) || (*text_ptr == DC3) ) 
  825.       text_ptr++;
  826.  
  827.     /* CR -- skip and print */
  828.     else if ( *text_ptr == CARRIAGE_RETURN ) {
  829.       text_ptr += DQ_EOL_LEN;    /* CR, LF */
  830.       PRINT_LINE(line, ndx, line_cnt,text_ptr,last_ptr,continue_viewing);
  831.     }
  832.  
  833.     else {
  834.       line[ndx++] = *text_ptr++;
  835.       if ( ndx > DQ_MAX_LINE_LEN ) {
  836.     printf("**** ERROR in display text -- line too long %ld\n", ndx);
  837.     return;
  838.       }
  839.     }
  840.   }                /* end while */
  841.  
  842.   if ( text_ptr >= last_ptr ) {
  843.     printf("**** ERROR in display text -- could not find End Of Text\n");
  844.     return;
  845.   }
  846.  
  847.   if ( ndx > 0 ) {
  848.     line[ndx] = NULL;
  849.     line_cnt++; 
  850.     printf("%s\n", line);
  851.   }
  852.  
  853.  
  854. }                /* dsply_text */
  855. #endif
  856.  
  857. static void dsply_text _AP((long size,char* text));
  858.  
  859. static void dsply_text( size, text)
  860. long size;
  861. char *text;
  862. {
  863.   char *text_ptr, *last_ptr;
  864.   long line_cnt = 0;
  865.   long continue_viewing = 1;
  866.   char buff[3200];
  867.   long len;
  868.   char *buff_start, *buff_ptr;
  869.     
  870.   text_ptr = text;
  871.  
  872.   buff_start = &buff[0];    
  873.   buff_ptr = buff_start;
  874.   
  875.   last_ptr = text_ptr + size;
  876.  
  877.   while ( (text_ptr <= last_ptr) && (continue_viewing == 1) ) {
  878.     /* control markers */
  879.     if (  *text_ptr == ESC ) {
  880.       text_ptr++;
  881.       text_ptr++;
  882.     }
  883.     /* highlight & dehighlight markers -- skip */
  884.     else if (*text_ptr == DC1 || *text_ptr == DC3)
  885.       text_ptr++;
  886.     else if (*text_ptr == ETS)
  887.       text_ptr++;
  888.     else if ( *text_ptr == CARRIAGE_RETURN ) {
  889.       text_ptr++;        /* CR */
  890.       *buff_ptr++= CARRIAGE_RETURN;
  891.       *buff_ptr++ = LINE_FEED;
  892.       line_cnt++;
  893.       if ( (line_cnt == TEXT_LINES_PER_PAGE) && 
  894.       (text_ptr <= last_ptr)) {
  895.     len = (long)buff_ptr - (long) buff_start;
  896.     fwrite( buff_start, len, 1, stdout);
  897.     line_cnt = 0;
  898.     buff_ptr = buff_start;
  899.     printf("\n  ... more to come, enter 1 to continue or 0 to stop: ");
  900.     scanf("%ld", &continue_viewing);
  901.       }
  902.     }
  903.     else 
  904.       *buff_ptr++ = *text_ptr++;
  905.   }                /* end while */
  906.  
  907.   if ( buff_ptr > buff_start) {
  908.     len = (long)buff_ptr - (long)buff_start;
  909.     fwrite( buff_start, len,  1, stdout);
  910.   }
  911.  
  912. }                /* dsply_text */
  913.  
  914. static void dsply_text_record _AP((WAISDocumentText*  record));
  915.  
  916. static void dsply_text_record( record)
  917. WAISDocumentText *record;
  918. /*
  919.  * 'dsply_text_record'
  920.  *   display one WAIS text record 
  921.  */
  922. {
  923.   printf(" Text\n");
  924.   print_any("     DocumentID:  ", record->DocumentID);
  925.  
  926.   printf("     VersionNumber:  %ld\n", record->VersionNumber);
  927.   dsply_text( record->DocumentText->size,
  928.          record->DocumentText->bytes);
  929. }
  930.  
  931. static void dsply_headline_record _AP((WAISDocumentHeadlines*  record));
  932.  
  933. static void dsply_headline_record( record)
  934. WAISDocumentHeadlines *record;
  935. /*
  936.  * 'dsply_headline_record'
  937.  *   display one WAIS headline record 
  938.  */
  939. {
  940.   printf(" Headlines\n");
  941.   print_any("     DocumentID:  ", record->DocumentID);
  942.  
  943.   printf("     VersionNumber:  %ld\n", record->VersionNumber);
  944.  
  945.   if ( record->Source )
  946.     printf("     Source:  %s\n", record->Source);
  947.  
  948.   if ( record->Date )
  949.     printf("     Date:  %s\n", record->Date);
  950.  
  951.   if ( record->OriginCity)
  952.     printf("     OriginCity:  %s\n", record->OriginCity);
  953.   print_hdline(record->Headline);
  954.  
  955.   if ( record->Headline)
  956. #ifdef FOR_DUM_TERM
  957.     print_hdline(record->Headline);
  958. #else
  959.   printf("     Headline:  %s\n", record->Headline);
  960. #endif
  961. }
  962.  
  963. static void dsply_code_record _AP((WAISDocumentCodes*  record));
  964.  
  965. static void dsply_code_record( record)
  966. WAISDocumentCodes  *record;
  967. /*
  968.  * 'dsply_code_record'
  969.  *   display one WAIS code record 
  970.  */
  971. {
  972.   printf(" Codes\n");
  973.   print_any("     DocumentID:  ", record->DocumentID);
  974.  
  975.   printf("     VersionNumber:  %ld\n", record->VersionNumber);
  976.  
  977.   if ( record->StockCodes)
  978.     printf("     StockCodes:  %s", record->StockCodes);
  979.  
  980.   if ( record->CompanyCodes )
  981.     printf("     CompanyCodes:  %s", record->CompanyCodes);
  982.  
  983.   if ( record->IndustryCodes)
  984.     printf("     IndustryCodes:  %s", record->IndustryCodes);
  985.  
  986.   printf("\n");
  987. }
  988.  
  989.  
  990. /*
  991.  * "twais_dsply_rsp_apdu"
  992.  *   display response apdu on stdout
  993.  *   the response apdu is in the specified buffer
  994.  */
  995. void
  996. twais_dsply_rsp_apdu(rsp_buff, rsp_len)
  997. char *rsp_buff;         /* (I) buffer contain response apdu */
  998. long  rsp_len;           /* (I) number of bytes in the buffer */
  999. {
  1000.  
  1001.   pdu_type pdu;
  1002.   pdu = peekPDUType(rsp_buff);
  1003.   switch ( pdu) {
  1004.   case initResponseAPDU:
  1005.     twais_dsply_init_rsp_apdu( rsp_buff);
  1006.     break;
  1007.   case searchResponseAPDU:
  1008.     twais_dsply_srch_rsp_apdu( rsp_buff);
  1009.     break;
  1010.  
  1011.   case initAPDU:
  1012.     twais_dsply_init_apdu( rsp_buff);
  1013.     break;
  1014.   case searchAPDU:
  1015.     twais_dsply_srch_apdu( rsp_buff);
  1016.     break;
  1017.   default:
  1018.     /* others not supported yet */
  1019.     break;
  1020.   }
  1021.  
  1022. }                /* twais_dsply_rsp_apdu */
  1023.  
  1024.  
  1025. /*
  1026.  * "twais_dsply_init_rsp_apdu"
  1027.  *   display init response apdu on stdout
  1028.  *   the response apdu is encoded in the specified buffer
  1029.  */
  1030. void
  1031. twais_dsply_init_rsp_apdu( buffer)
  1032. char *buffer;           /* (I) buffer contain the init response apdu */
  1033. {
  1034.  
  1035.   InitResponseAPDU *response;
  1036.   WAISInitResponse *info;
  1037.   long i, len;
  1038.  
  1039.   printf("\n\n Init Response:\n");
  1040.  
  1041.   readInitResponseAPDU(&response,buffer);
  1042.  
  1043.   printf("    willSearch: %ld,  willPresent: %ld,  willDelete: %ld\n", 
  1044.      response->willSearch, 
  1045.      response->willPresent,
  1046.      response->willDelete);
  1047.   printf("    supportAccessControl: %ld,  supportResourceControl: %ld\n",
  1048.      response->supportAccessControl,
  1049.      response->supportResourceControl);
  1050.   printf("    PreferredMessageSize: %ld,  MaximumRecordSize: %ld\n",
  1051.      response->PreferredMessageSize, 
  1052.      response->MaximumRecordSize);
  1053.   if ( response->ImplementationID != 0) {
  1054.     printf("    ImplementationID: %s\n", 
  1055.        response->ImplementationID);   
  1056.   }
  1057.   if ( response->ImplementationName != 0) {
  1058.     printf("    ImplementationName: %s\n",
  1059.        response->ImplementationName);   
  1060.   }
  1061.   if ( response->ImplementationVersion != 0) {
  1062.     printf("    ImplementationVersion: %s\n",
  1063.        response->ImplementationVersion);   
  1064.   }
  1065.   if ( response->ReferenceID != 0) {
  1066.     print_any("    ReferenceID: ", response->ReferenceID);
  1067.   }
  1068.  
  1069.   if ( response->UserInformationField != 0) {
  1070.     info = (WAISInitResponse *)response->UserInformationField;
  1071.     printf("    ChunkCode: %ld,  ChunkIDLength: %ld\n",
  1072.        info->ChunkCode,
  1073.        info->ChunkIDLength);
  1074.  
  1075.     printf("    ChunkMarker: ");
  1076.     len = strlen( info->ChunkMarker);
  1077.     for ( i=0; i< len; i++)
  1078.       printf("%ld, ", info->ChunkMarker[i]);
  1079.     printf("\n");
  1080.  
  1081.     printf("    HighlightMarker: ");
  1082.     len = strlen( info->HighlightMarker);
  1083.     for ( i=0; i< len; i++)
  1084.       printf("%ld, ", info->HighlightMarker[i]);
  1085.     printf("\n");
  1086.  
  1087.     printf("    DeHighlightMarker: ");
  1088.     len = strlen( info->DeHighlightMarker);
  1089.     for ( i=0; i< len; i++)
  1090.       printf("%ld, ", info->DeHighlightMarker[i]);
  1091.     printf("\n");
  1092.  
  1093.     printf("    NewlineCharacters: ");
  1094.     len = strlen( info->NewlineCharacters);
  1095.     for ( i=0; i< len; i++)
  1096.       printf("%ld, ", info->NewlineCharacters[i]);
  1097.     printf("\n");
  1098.  
  1099.   }
  1100.   freeInitResponseAPDU( response);
  1101.  
  1102. }                /* twais_dsply_init_rsp_apdu */
  1103.  
  1104. /*
  1105.  * "twais_dsply_init_apdu"
  1106.  *   display init apdu on stdout
  1107.  *   the apdu is in the specified buffer
  1108.  */
  1109. void
  1110. twais_dsply_init_apdu( buffer)
  1111. char *buffer;           /* (I) buffer contain the init response apdu */
  1112. {
  1113.  
  1114.   InitAPDU *init;
  1115.  
  1116.   printf("\n\n Init Request:\n");
  1117.  
  1118.   readInitAPDU(&init,buffer);
  1119.  
  1120.   printf("    willSearch: %ld,  willPresent: %ld,  willDelete: %ld\n", 
  1121.      init->willSearch, 
  1122.      init->willPresent,
  1123.      init->willDelete);
  1124.   printf("    supportAccessControl: %ld,  supportResourceControl: %ld\n",
  1125.      init->supportAccessControl,
  1126.      init->supportResourceControl);
  1127.   printf("    PreferredMessageSize: %ld,  MaximumRecordSize: %ld\n",
  1128.      init->PreferredMessageSize, 
  1129.      init->MaximumRecordSize);
  1130.  
  1131.   if ( init->IDAuthentication != 0) {
  1132.     printf("    IDAuthentication: %s\n", 
  1133.        init->IDAuthentication);   
  1134.   }
  1135.  
  1136.   if ( init->ImplementationID != 0) {
  1137.     printf("    ImplementationID: %s\n", 
  1138.        init->ImplementationID);   
  1139.   }
  1140.  
  1141.   if ( init->ImplementationName != 0) {
  1142.     printf("    ImplementationName: %s\n",
  1143.        init->ImplementationName);   
  1144.   }
  1145.  
  1146.   if ( init->ImplementationVersion != 0) {
  1147.     printf("    ImplementationVersion: %s\n",
  1148.        init->ImplementationVersion);   
  1149.   }
  1150.  
  1151.   if ( init->ReferenceID != 0) {
  1152.     print_any("    ReferenceID: ", init->ReferenceID);
  1153.   }
  1154.  
  1155.   freeInitAPDU( init);
  1156.  
  1157. }                /* twais_dsply_init_apdu */
  1158.  
  1159. /*
  1160.  * "twais_dsply_srch_rsp_apdu"
  1161.  *   display search response apdu on stdout
  1162.  *   the response apdu is encoded in the specified buffer
  1163.  */
  1164. void
  1165. twais_dsply_srch_rsp_apdu( buffer)
  1166. char *buffer;           /* (I) buffer contain the search response apdu */
  1167. {
  1168.   SearchResponseAPDU  *response;
  1169.   WAISSearchResponse  *info;
  1170.   long continue_viewing;
  1171.   long i, k;
  1172.  
  1173.   printf("\n\n Search Response:\n");
  1174.  
  1175.   readSearchResponseAPDU(&response,buffer);
  1176.   printf("    SearchStatus:            %ld\n", response->SearchStatus); 
  1177.   printf("    ResultCount:             %ld\n", response->ResultCount); 
  1178.   printf("    NumberOfRecordsReturned: %ld\n", response->NumberOfRecordsReturned); 
  1179.   printf("    PresentStatus:           %ld\n", response->PresentStatus); 
  1180.   if ( response->ReferenceID != 0 )
  1181.     print_any("    ReferenceID:             ", response->ReferenceID);
  1182.  
  1183.   if ( response->DatabaseDiagnosticRecords != 0 ) {
  1184.     info = (WAISSearchResponse *)response->DatabaseDiagnosticRecords;
  1185.     if ( info->SeedWordsUsed != 0 )
  1186.       printf("    SeedWordsUsed:           %s\n", info->SeedWordsUsed); 
  1187.  
  1188.     i =0; 
  1189.     continue_viewing = 1; 
  1190.  
  1191.     if ( info->DocHeaders != 0 ) {
  1192.       k =0;
  1193.       while ( (continue_viewing == 1) && info->DocHeaders[k] != 0 ) {
  1194.     i++;
  1195.     printf("\n    record %2d, ", i);
  1196.     dsply_doc_hdr_record( info->DocHeaders[k++]);
  1197. #ifdef FOR_DUM_TERM
  1198.     if ( i < response->NumberOfRecordsReturned ) {
  1199.       printf("\n\n  ... more to come,  enter 1 to continue or 0 to stop: ");
  1200.       scanf("%ld", &continue_viewing);
  1201.     }
  1202. #endif
  1203.       }
  1204.     }
  1205.  
  1206.     if ( info->ShortHeaders != 0 ) {
  1207.       k =0;
  1208.       while ( (continue_viewing == 1) && info->ShortHeaders[k] != 0 ) {
  1209.     i++;
  1210.     printf("\n    record %2d, ", i);
  1211.     dsply_short_hdr_record( info->ShortHeaders[k++]);
  1212. #ifdef FOR_DUM_TERM
  1213.     if ( i < response->NumberOfRecordsReturned ) {
  1214.       printf("\n\n  ... more to come,  enter 1 to continue or 0 to stop: ");
  1215.       scanf("%ld", &continue_viewing);
  1216.     }
  1217. #endif
  1218.       }
  1219.     }
  1220.  
  1221.     if ( info->LongHeaders != 0 ) {
  1222.       k =0;
  1223.       while ( (continue_viewing == 1) && (info->LongHeaders[k] != 0) ) {
  1224.     i++;
  1225.     printf("\n    record %2d, ", i);
  1226.     dsply_long_hdr_record( info->LongHeaders[k++]);
  1227. #ifdef FOR_DUM_TERM
  1228.     if ( i < response->NumberOfRecordsReturned ) {
  1229.       printf("\n\n  ... more to come,  enter 1 to continue or 0 to stop: ");
  1230.       scanf("%ld", &continue_viewing);
  1231.     }
  1232. #endif
  1233.       }
  1234.     }
  1235.  
  1236.     if ( info->Text != 0 ) {
  1237.       k =0;
  1238.       while ( (continue_viewing == 1) && (info->Text[k] != 0) ) {
  1239.     i++;
  1240.     printf("\n    record %2d, ", i);
  1241.     dsply_text_record( info->Text[k++]);
  1242. #ifdef FOR_DUM_TERM
  1243.     if ( i < response->NumberOfRecordsReturned ) {
  1244.       printf("\n\n  ... more to come,  enter 1 to continue or 0 to stop: ");
  1245.       scanf("%ld", &continue_viewing);
  1246.     }
  1247. #endif
  1248.       }
  1249.     }
  1250.  
  1251.     if ( info->Headlines != 0 ) {
  1252.       k =0;
  1253.       while ( (continue_viewing ==1) && (info->Headlines[k] != 0) ) {
  1254.     i++;
  1255.     printf("\n    record %2d, ", i);
  1256.     dsply_headline_record( info->Headlines[k++]);
  1257. #ifdef DUM_TERM
  1258.     if ( i < response->NumberOfRecordsReturned ) {
  1259.       printf("\n\n  ... more to come,  enter 1 to continue or 0 to stop: ");
  1260.       scanf("%ld", &continue_viewing);
  1261.     }
  1262. #endif
  1263.       }
  1264.     }
  1265.          
  1266.     if ( info->Codes != 0 ) {
  1267.       k =0;
  1268.       while ( (continue_viewing ==1) && (info->Codes[k] != 0) ) {
  1269.     i++;
  1270.     printf("\n    record %2d, ", i);
  1271.     dsply_code_record( info->Codes[k++]);
  1272. #ifdef FOR_DUM_TERM
  1273.     if ( i < response->NumberOfRecordsReturned ) {
  1274.       printf("\n\n  ... more to come,  enter 1 to continue or 0 to stop: ");
  1275.       scanf("%ld", &continue_viewing);
  1276.     }
  1277. #endif
  1278.       }
  1279.     }
  1280.  
  1281.     freeWAISSearchResponse(info);         
  1282.  
  1283.   }                /* display user info */
  1284.  
  1285.  
  1286.   freeSearchResponseAPDU( response);
  1287.  
  1288. }                /* twais_dsply_srch_rsp_apdu */
  1289.  
  1290.  
  1291. /*
  1292.  * 'dsply_doc_hdr_record'
  1293.  *   display one WAIS document header record 
  1294.  */
  1295. dsply_doc_hdr_record( record)
  1296. WAISDocumentHeader  *record;
  1297. {
  1298.   printf(" DocHeaders\n");
  1299.   print_any("     DocumentID:  ", record->DocumentID);
  1300.  
  1301.   printf("     VersionNumber:  %ld\n", record->VersionNumber);
  1302.  
  1303.   printf("     Score:  %ld,  BestMatch:  %ld\n", 
  1304.      record->Score, record->BestMatch);
  1305.  
  1306.   printf("     DocumentLength:  %ld,  Lines:  %ld\n", 
  1307.      record->DocumentLength,
  1308.      record->Lines);
  1309.  
  1310.   if ( record->Source )
  1311.     printf("     Source:  %s\n", record->Source);
  1312.   if ( record->Date  )
  1313.     printf("     Date:  %s\n", record->Date);
  1314.  
  1315.   if ( record->OriginCity )
  1316.     printf("     OriginCity:  %s\n", record->OriginCity);
  1317.  
  1318.   if ( record->Headline )
  1319. #ifdef FOR_DUM_TERM
  1320.     print_hdline(record->Headline);
  1321. #else
  1322.   printf("     Headline:  %s\n", record->Headline);
  1323. #endif
  1324. }
  1325.  
  1326. /*
  1327.  * 'dsply_short_hdr_record'
  1328.  *   display one WAIS short header record 
  1329.  */
  1330. dsply_short_hdr_record( record)
  1331. WAISDocumentShortHeader  *record;
  1332. {
  1333.   printf(" ShortHeaders\n");
  1334.   print_any("     DocumentID:  ", record->DocumentID);
  1335.  
  1336.   printf("     VersionNumber:  %ld\n", record->VersionNumber);
  1337.   printf("     Score:  %ld,  BestMatch:  %ld\n", 
  1338.      record->Score, record->BestMatch);
  1339.   printf("     DocumentLength:  %ld,  Lines:  %ld\n", 
  1340.      record->DocumentLength,  record->Lines);
  1341. }
  1342.  
  1343. static void print_docs _AP((DocObj** docs));
  1344.  
  1345. static void print_docs( docs)
  1346. DocObj **docs;
  1347. {
  1348.   long i;
  1349.  
  1350.   for ( i=0; docs[i] !=0; i++ ) {
  1351.     printf("    Document %ld:\n", i+1 );
  1352.     print_any("     DocID: ", docs[i]->DocumentID);
  1353.     if (docs[i]->Type != NULL)
  1354.       printf("     Type: %s\n",docs[i]->Type);
  1355.     printf("     ChunkCode: %ld\n", docs[i]->ChunkCode);
  1356.     switch ( docs[i]->ChunkCode ) {
  1357.     case CT_byte:
  1358.     case CT_line:
  1359.       printf("     Range: (%ld, %ld)\n", docs[i]->ChunkStart.Pos,
  1360.          docs[i]->ChunkEnd.Pos);
  1361.       break;
  1362.     case CT_paragraph:
  1363.       print_any("     Chunk Start: ", docs[i]->ChunkStart.ID);
  1364.       print_any("     Chunk End:   ", docs[i]->ChunkEnd.ID);
  1365.       break;
  1366.     case CT_document:
  1367.     default:
  1368.       break;
  1369.     }
  1370.   }
  1371.  
  1372. }                /* print_docs */
  1373.  
  1374.  
  1375. /*
  1376.  * "twais_dsply_srch_apdu"
  1377.  *   display search apdu on stdout
  1378.  *   the  apdu is in the specified buffer
  1379.  */
  1380. void
  1381. twais_dsply_srch_apdu( buffer)
  1382. char *buffer;           /* (I) buffer contain the search apdu */
  1383. {
  1384.   SearchAPDU  *search;
  1385.   WAISSearch  *info;
  1386.   DocObj **docs;
  1387.   any *text_search;
  1388.   long i;
  1389.  
  1390.   printf("\n\n Search Request:\n");
  1391.  
  1392.   readSearchAPDU(&search,buffer);
  1393.  
  1394.   printf("    SmallSetUpperBound:      %ld\n", search->SmallSetUpperBound); 
  1395.   printf("    LargeSetLowerBound:      %ld\n", search->LargeSetLowerBound); 
  1396.   printf("    MediumSetPresentNumber:  %ld\n", search->MediumSetPresentNumber); 
  1397.   printf("    ReplaceIndicator:        %ld\n", search->ReplaceIndicator); 
  1398.   if ( search->ResultSetName != 0 )
  1399.     printf("    ResultSetName:           %s\n", search->ResultSetName); 
  1400.   if ( search->QueryType != 0 )
  1401.     printf("    QueryType:               %s\n", search->QueryType); 
  1402.   if ( search->DatabaseNames != 0 )
  1403.     for ( i=0; search->DatabaseNames[i] != 0 ; i++ )
  1404.       printf("    Databasenames[%ld]:          %s\n", i,
  1405.          search->DatabaseNames[i]);
  1406.  
  1407.   if ( search->ElementSetNames != 0 )
  1408.     for ( i=0; search->ElementSetNames[i] != 0 ; i++ )
  1409.       printf("    ElementSetNames[%ld]:        %s\n", i,
  1410.          search->ElementSetNames[i]);
  1411.   
  1412.  
  1413.   if ( search->ReferenceID != 0 )
  1414.     print_any("    ReferenceID:             ", search->ReferenceID);
  1415.  
  1416.   if ( search->Query != 0 ) {
  1417.  
  1418.     /* type 1 */
  1419.     if ( ! strcmp( search->QueryType, QT_TextRetrievalQuery) ) {
  1420.       text_search = (any *) search->Query;
  1421.       docs = readWAISTextQuery(text_search);
  1422.       if ( docs != 0 )
  1423.     print_docs( docs);
  1424.       freeAny(text_search);
  1425.       doList((void**)docs,freeDocObj);
  1426.       s_free(docs);
  1427.     }
  1428.  
  1429.     else if ( ! strcmp( search->QueryType, QT_RelevanceFeedbackQuery) ) {
  1430.  
  1431.       info = (WAISSearch *)search->Query;
  1432.       if ( info->SeedWords != 0 )
  1433.     printf("    SeedWords:               %s\n", info->SeedWords); 
  1434.       if ( info->Docs != 0 )
  1435.     print_docs( info->Docs);
  1436.       printf("    DateFactor: %ld\n", info->DateFactor);
  1437.       if ( info->BeginDateRange )
  1438.     printf("    BeginDateRange: %s\n", info->BeginDateRange);
  1439.       if ( info->EndDateRange )
  1440.     printf("    EndDateRange:   %s\n", info->EndDateRange);
  1441.       printf("    MaxDocumentsRetrieved: %ld\n", info->MaxDocumentsRetrieved);
  1442.  
  1443.       freeWAISSearch(info);         
  1444.     }
  1445.     else {
  1446.       printf(" Unrecognized query type\n");
  1447.     }
  1448.   }
  1449.  
  1450.   freeSearchAPDU( search);
  1451.  
  1452. }                /* twais_dsply_srch_apdu */
  1453.  
  1454.  
  1455. void twais_free_apdu(apdu_buff)
  1456. char *apdu_buff;        /* (I) buffer contain the apdu */
  1457. {
  1458.   pdu_type pdu;
  1459.  
  1460.   pdu = peekPDUType(apdu_buff);
  1461.   switch ( pdu) {
  1462.   case (initAPDU):
  1463.     freeInitAPDU((struct InitAPDU *)apdu_buff);
  1464.     break;
  1465.   case (initResponseAPDU):
  1466.     freeInitResponseAPDU((struct InitResponseAPDU *)apdu_buff);
  1467.     break;
  1468.   case (searchAPDU):
  1469.     freeSearchAPDU((struct SearchAPDU *)apdu_buff);
  1470.     break;
  1471.   case (searchResponseAPDU):
  1472.     freeSearchResponseAPDU((struct SearchResponseAPDU *)apdu_buff);
  1473.     break;
  1474.   default:
  1475.     break;
  1476.   }
  1477.   
  1478. }                /* twais_free_apdu */
  1479.  
  1480.  
  1481. /*----------------------------------------------------------------------------*
  1482.  *  template apdus for testing purpose                                        *
  1483.  *----------------------------------------------------------------------------*/
  1484. void
  1485. twais_tmplt_init_apdu(buff, buff_len)
  1486. char *buff;             /* (O) buffer to hold the apdu */
  1487. long *buff_len;          /* (O) number of bytes written to the buffer */
  1488. {
  1489.   InitAPDU *init;
  1490.   char  *end_ptr;
  1491.   long len;
  1492.   any refID;
  1493.   refID.size = 2;
  1494.   refID.bytes = "10";
  1495.  
  1496.  
  1497.   init = makeInitAPDU(WILL_USE,WILL_NOT_USE,WILL_NOT_USE,WILL_NOT_SUPPORT,
  1498.               WILL_NOT_SUPPORT,
  1499.               2048L,
  1500.               2048L, NULL,
  1501.               defaultImplementationID(),defaultImplementationName(),
  1502.               defaultImplementationVersion(), &refID,NULL);
  1503.   { long buffer_len = MAX_BUFFER_LENGTH;
  1504.     end_ptr = writeInitAPDU(init,buff, &buffer_len);
  1505.   }
  1506.   len = (long)end_ptr - (long)&buff[0];
  1507.   *buff_len = len;
  1508.   freeInitAPDU(init);
  1509. }                /* twais_tmplt_init_apdu */
  1510.  
  1511.  
  1512. void
  1513. twais_tmplt_init_rsp_apdu(buff, buff_len)
  1514. char *buff;             /* (O) buffer to hold the apdu */
  1515. long *buff_len;          /* (O) number of bytes written to the buffer */
  1516. {
  1517.   WAISInitResponse *info;
  1518.   InitResponseAPDU *response;
  1519.   char  *end_ptr;
  1520.   long len;
  1521.   any refID;
  1522.   char chunk_marker[3];
  1523.   char highl_marker[2];
  1524.   char dhighl_marker[2];
  1525.   char new_line_chars[2];
  1526.   refID.size = 1;
  1527.   refID.bytes = "0";
  1528.   chunk_marker[0] = ESC;
  1529.   chunk_marker[1] = '1';
  1530.   chunk_marker[2]= 0;
  1531.   highl_marker[0] = DC1;
  1532.   highl_marker[1] = 0;
  1533.   dhighl_marker[0] = DC3;
  1534.   dhighl_marker[1] = 0;
  1535.   new_line_chars[0] = CARRIAGE_RETURN;
  1536.   new_line_chars[1] = 0;
  1537.  
  1538.   info =  makeWAISInitResponse(  CT_paragraph /* chunkCode */
  1539.                    ,3 /* chunkIDLen */
  1540.                    ,chunk_marker /* chunkMarker */
  1541.                    ,highl_marker /* highlightMarker */
  1542.                    ,dhighl_marker /* deHighlightMarker */
  1543.                    ,new_line_chars /* newLineChars */
  1544.                    );
  1545.  
  1546.   response = makeInitResponseAPDU( ACCEPT, /* result */
  1547.                   WILL_USE,WILL_NOT_USE,WILL_NOT_USE, /* search, rsp, del */
  1548.                   WILL_NOT_SUPPORT,WILL_NOT_SUPPORT, /* acc ctl, rsc ctl */
  1549.                   1024L, 2048L, /* preferred msg size, max msg size */
  1550.                   NULL,    /* authentication */
  1551.                   defaultImplementationID(),
  1552.                   defaultImplementationName(),
  1553.                   defaultImplementationVersion(),
  1554.                   &refID, /* reference id */
  1555.                   info);
  1556.   { long buffer_len = MAX_BUFFER_LENGTH;
  1557.     end_ptr = writeInitResponseAPDU(response, buff, &buffer_len);
  1558.   }
  1559.   len = (long)end_ptr - (long)&buff[0];
  1560.   *buff_len = len;
  1561.  
  1562.   CSTFreeWAISInitResponse( info);
  1563.   freeInitResponseAPDU(response);
  1564. }                /* twais_tmplt_init_rsp_apdu */
  1565.  
  1566.  
  1567.  
  1568. void twais_tmplt_typ1_srch_apdu( buff, buff_len)
  1569. char *buff;             /* (O) buffer to hold the apdu */
  1570. long *buff_len;          /* (O) number of bytes written to the buffer */
  1571. {
  1572.  
  1573.   SearchAPDU *search1;
  1574.   char  *end_ptr;
  1575.   long len;
  1576.  
  1577.   static char *database_names[2];
  1578.   any docID;
  1579.   any refID;
  1580.  
  1581.   DocObj *DocObjs[2];
  1582.   any *query;            /* changed from char* by brewster */
  1583.   database_names[0] = "Quest";
  1584.   database_names[1] = NULL;
  1585.   docID.size = 12;
  1586.   docID.bytes = "0000106776WJ";
  1587.   refID.size = 1;
  1588.   refID.bytes = "3";
  1589.    
  1590.   DocObjs[0] = makeDocObjUsingWholeDocument( &docID,NULL);
  1591.   DocObjs[1] = NULL;
  1592.  
  1593.   query = makeWAISTextQuery(DocObjs);   
  1594.  
  1595.   search1 = makeSearchAPDU( 10L, 16L, 15L, 
  1596.                1L,    /* replace indicator */
  1597.                "FOO", /* result set name */
  1598.                database_names, /* database name */   
  1599.                QT_TextRetrievalQuery, /* query_type */
  1600.                0L,    /* element name */
  1601.                &refID, /* reference ID */
  1602.                query);
  1603.  
  1604.   {
  1605.     long buffer_len = MAX_BUFFER_LENGTH;
  1606.     end_ptr = writeSearchAPDU(  search1, buff, &buffer_len);
  1607.   }
  1608.   len = (long)end_ptr - (long)&buff[0];
  1609.   *buff_len = len;
  1610.  
  1611.   CSTFreeWAISTextQuery( query);
  1612.   freeSearchAPDU(search1);
  1613.  
  1614. }                /* twais_tmplt_typ1_srch_apdu */
  1615.  
  1616. #if 0
  1617.  
  1618. twais_tmplt_typ3_srch_apdu( buff, buff_len)
  1619. char *buff;             /* (O) buffer to hold the apdu */
  1620. long *buff_len;          /* (O) number of bytes written to the buffer */
  1621. {
  1622.  
  1623.   SearchAPDU *search3;
  1624.   char  *end_ptr;
  1625.   static char *database_names[2];
  1626.   long len;
  1627.   any refID;
  1628.   WAISSearch *query;
  1629.   database_names[0] = "Quest"
  1630.     database_names[1] = NULL;
  1631.   refID.size = 1;
  1632.   refID.bytes = "3";
  1633.  
  1634.   query = makeWAISSearch( "Supercomputers in Taiwan", /* seed_words*/
  1635.              0L,    /* DocObjsPtr */
  1636.              0L,
  1637.              1L,    /* DateFactor */
  1638.              0L,    /* BeginDateRange */
  1639.              0L,    /* EndDateRange */
  1640.              10L    /* maxDocsRetrieved */
  1641.              );
  1642.  
  1643.   search3 = makeSearchAPDU( 10L, 16L, 15L, 
  1644.                1L,    /* replace indicator */
  1645.                "FOO", /* result set name */
  1646.                database_names, /* database name */   
  1647.                QT_RelevanceFeedbackQuery, /* query_type */
  1648.                0L,    /* element name */
  1649.                &refID, /* reference ID */
  1650.                query);
  1651.   {
  1652.     long buffer_len = MAX_BUFFER_LENGTH;
  1653.     end_ptr = writeSearchAPDU(  search3, buff, &buffer_len);
  1654.   }
  1655.   len = (long)end_ptr - (long)&buff[0];
  1656.   *buff_len = len;
  1657.  
  1658.   CSTFreeWAISSearch( query);
  1659.   freeSearchAPDU(search3);
  1660.  
  1661. }                /* twais_tmplt_typ3_srch_apdu */
  1662. #endif
  1663.  
  1664.  
  1665. void twais_tmplt_typ3_srch_rsp_apdu( buff, buff_len)
  1666. char *buff;
  1667. long *buff_len;
  1668. {
  1669.  
  1670.   char  *end_ptr;
  1671.   long len;
  1672.   any refID;
  1673.  
  1674.   WAISDocumentHeader  *doc_headers[3];
  1675.   WAISSearchResponse *records;
  1676.   SearchResponseAPDU *response;
  1677.   any doc_id1;
  1678.   any doc_id2;
  1679.   refID.size = 1;
  1680.   refID.bytes = "1";
  1681.   doc_id1.size = 12;   
  1682.   doc_id1.bytes = "0000106776WJ";
  1683.   doc_id2.size = 12;
  1684.   doc_id2.bytes = "0000026870WP";
  1685.  
  1686.   doc_headers[0] = makeWAISDocumentHeader(
  1687.                       &doc_id1, /* docID */
  1688.                       1L, /* versionNumber */
  1689.                       80L, /* score */
  1690.                       1L, /* bestMatch */
  1691.                       850L, /* docLen */
  1692.                       200L, /* lines */
  1693.                       NULL,    /* types */
  1694.                       "Source1", /* source */
  1695.                       "19900115", /* date */
  1696.                       "CRAY sells supercomputer to Taiwan",    /* headline */
  1697.                       "New York"); /* originCity */
  1698.  
  1699.  
  1700.   doc_headers[1] = makeWAISDocumentHeader(
  1701.                       &doc_id2, /* docID */
  1702.                       1L, /* versionNumber */
  1703.                       60L, /* score */
  1704.                       1L, /* bestMatch */
  1705.                       550L, /* docLen */
  1706.                       100L, /* lines */
  1707.                       NULL,
  1708.                       "Test Source", /* source */
  1709.                       "19900110", /* date */
  1710.                       "Test Headline", /* headline */
  1711.                       "Test City");    /* originCity */
  1712.  
  1713.   doc_headers[2] = 0;
  1714.  
  1715.   records = makeWAISSearchResponse( "Supercomputer Taiwan" /* seedWordsUsed*/
  1716.                    ,doc_headers    /* docHeaders */
  1717.                    ,0 ,0 ,0 ,0 /* shortHeaders, longHeaders, text, headlines */
  1718.                    ,0 /* codes */
  1719.                    ,NULL /* diagnostics.  KLUDGE */
  1720.                    );
  1721.  
  1722.  
  1723.   response = makeSearchResponseAPDU( SUCCESS /* result */
  1724.                     ,2 /* count */
  1725.                     ,2 /* recordsReturned */
  1726.                     ,0 /* nextPos */
  1727.                     ,0 /* ignore resultStatus since result SUCCESS */
  1728.                     ,SUCCESS /* presentStatus */
  1729.                     ,&refID /* refID */
  1730.                     ,records);
  1731.  
  1732.  
  1733.   {
  1734.     long buffer_len = MAX_BUFFER_LENGTH;
  1735.     end_ptr = writeSearchResponseAPDU(  response, buff, &buffer_len);
  1736.   }
  1737.   len = (long)end_ptr - (long)&buff[0];
  1738.   *buff_len = len;
  1739.  
  1740.   CSTFreeWAISDocumentHeader( doc_headers[0]);
  1741.  
  1742.   CSTFreeWAISDocumentHeader( doc_headers[1]);
  1743.  
  1744.   CSTFreeWAISSearchResponse( records);
  1745.   freeSearchResponseAPDU(response);
  1746.  
  1747.  
  1748. }                /* twais_tmplt_typ3_srch_rsp_apdu */
  1749.  
  1750.  
  1751. twais_tmplt_typ1_stry_rsp_apdu( buff, buff_len)
  1752. char *buff;
  1753. long *buff_len;
  1754. {
  1755.  
  1756.   char  *end_ptr;
  1757.   long len;
  1758.   any refID;
  1759.  
  1760.   WAISDocumentText *doc_text[2];
  1761.   WAISSearchResponse *records;
  1762.   SearchResponseAPDU *response;
  1763.   any docID;
  1764.   any story;
  1765.   char *story_buff;
  1766.   
  1767.   FILE *fptr;
  1768.   refID.size = 1;
  1769.   refID.bytes = "1";
  1770.   docID.size = 12;
  1771.   docID.bytes = "0000106776WJ";
  1772.   doc_text[0] = 0;
  1773.   doc_text[1] = 0;
  1774.  
  1775.   fptr = s_fopen("twais_template.txt", "r");
  1776.   if (fptr == NULL ) {
  1777.     printf(" unable to open story text file \n");
  1778.     return;
  1779.   }
  1780.    
  1781.   /* read story length */
  1782.   fread((char*)&story.size, sizeof(long), 1, fptr);
  1783.   story_buff = s_malloc( story.size +1);
  1784.   if ( story_buff == NULL) {
  1785.     printf(" insufficient memory\n");
  1786.     s_fclose( fptr);
  1787.     return;
  1788.   }
  1789.  
  1790.   /* read story text */
  1791.   fread( story_buff, 1, story.size, fptr);   
  1792.   story.bytes = story_buff;
  1793.    
  1794.   doc_text[0] = makeWAISDocumentText( &docID, 1L, &story);
  1795.  
  1796.   records = makeWAISSearchResponse( 0 /* seedWordsUsed*/
  1797.                    ,0 ,0 ,0 /* docHeaders, shortHeaders, longHeaders */
  1798.                    ,doc_text ,0    /* text, headlines */
  1799.                    ,0 /* codes */
  1800.                    ,NULL /* diagnostics.  KLUDGE */
  1801.                    );
  1802.  
  1803.  
  1804.   response = makeSearchResponseAPDU( SUCCESS /* result */
  1805.                     ,1 /* count */
  1806.                     ,1 /* recordsReturned */
  1807.                     ,0 /* nextPos */
  1808.                     ,0 /* ignore resultStatus since result SUCCESS */
  1809.                     ,SUCCESS /* presentStatus */
  1810.                     ,&refID /* refID */
  1811.                     ,records);
  1812.  
  1813.  
  1814.   {
  1815.     long buffer_len = MAX_BUFFER_LENGTH;
  1816.     end_ptr = writeSearchResponseAPDU(  response, buff, &buffer_len);
  1817.   }
  1818.   len = (long)end_ptr - (long)&buff[0];
  1819.   *buff_len = len;
  1820.  
  1821.   CSTFreeWAISDocumentText( doc_text[0]);
  1822.  
  1823.   CSTFreeWAISSearchResponse( records);
  1824.  
  1825.   freeSearchResponseAPDU(response);
  1826.  
  1827.   s_free(story_buff);
  1828.   s_fclose(fptr);
  1829.  
  1830. }                /* twais_tmplt_typ1_stry_rsp_apdu */
  1831.  
  1832.  
  1833. twais_tmplt_typ3_srch_apdu( buff, buff_len)
  1834. char *buff;             /* (O) buffer to hold the apdu */
  1835. long *buff_len;          /* (O) number of bytes written to the buffer */
  1836. {
  1837.  
  1838.   SearchAPDU *search3;
  1839.   char  *end_ptr;
  1840.   static char *database_names[7] = { 
  1841.     "11111111111111111111111111111111111111111111111111",
  1842.     "22222222222222222222222222222222222222222222222222",
  1843.     "33333333333333333333333333333333333333333333333333",
  1844.     "44444444444444444444444444444444444444444444444444",
  1845.     "55555555555555555555555555555555555555555555555555",
  1846.     "66666666666666666666666666666666666666666666666666",
  1847.     0};
  1848.   static char *elem_names[7] = { ES_DocumentHeader
  1849.                    ,ES_DocumentShortHeader
  1850.                      ,ES_DocumentLongHeader
  1851.                        ,ES_DocumentText
  1852.                      ,ES_DocumentHeadline
  1853.                        ,ES_DocumentCodes
  1854.                          ,0};
  1855.  
  1856.   long len;          
  1857.   any refID;
  1858.   WAISSearch *query;
  1859.   refID.size = 1;
  1860.   refID.bytes = "3";
  1861.  
  1862.   query = makeWAISSearch( 
  1863.              "What is the penalities for driving without insurance",
  1864.              0L,    /* DocObjsPtr */
  1865.              0L,
  1866.              1L,    /* DateFactor */
  1867.              0L,    /* BeginDateRange */
  1868.              0L,    /* EndDateRange */
  1869.              10L    /* maxDocsRetrieved */
  1870.              );
  1871.  
  1872.   search3 = makeSearchAPDU( 10L, 16L, 15L, 
  1873.                1L,    /* replace indicator */
  1874.                "FOO", /* result set name */
  1875.                database_names, /* database name */   
  1876.                QT_RelevanceFeedbackQuery, /* query_type */
  1877.                elem_names, /* element name */
  1878.                &refID, /* reference ID */
  1879.                query);
  1880.   {
  1881.     long buffer_len = MAX_BUFFER_LENGTH;
  1882.     end_ptr = writeSearchAPDU(  search3, buff, &buffer_len);
  1883.   }
  1884.   len = (long)end_ptr - (long)&buff[0];
  1885.   *buff_len = len;
  1886.  
  1887.   CSTFreeWAISSearch( query);
  1888.   freeSearchAPDU(search3);
  1889.  
  1890. }                /* twais_tmplt_typ3_srch_apdu */
  1891.  
  1892.